package com.loongair.gjmobile;

import android.app.Activity;
import android.content.Intent;
import androidx.annotation.NonNull;

import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableArray;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.Arguments;

import android.app.AlertDialog;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.os.Bundle;
import androidx.annotation.CallSuper;
import androidx.annotation.Nullable;
import com.facebook.react.ReactActivity;
import android.util.Base64;
import java.io.ByteArrayOutputStream;
import android.util.Log;
import android.widget.ImageView;

//import cn.org.bjca.anysign.android.R3.api.exceptions.CrashHandler;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import cn.org.bjca.anysign.android.api.Interface.OnSignatureResultListener;
//import cn.org.bjca.anysign.android.api.R;
import cn.org.bjca.anysign.android.api.core.BatchSignatureObj;
import cn.org.bjca.anysign.android.api.core.CachetObj;
import cn.org.bjca.anysign.android.api.core.CommentObj;
import cn.org.bjca.anysign.android.api.core.OriginalContent;
import cn.org.bjca.anysign.android.api.core.SignRule;
import cn.org.bjca.anysign.android.api.core.SignRule.KWRule;
import cn.org.bjca.anysign.android.api.core.SignRule.SignRuleType;
import cn.org.bjca.anysign.android.api.core.SignRule.XYZRule;
import cn.org.bjca.anysign.android.api.core.SignatureAPI;
import cn.org.bjca.anysign.android.api.core.SignatureObj;
import cn.org.bjca.anysign.android.api.core.Signer;
import cn.org.bjca.anysign.android.api.core.Signer.SignerCardType;
import cn.org.bjca.anysign.android.api.core.domain.AnySignBuild;
import cn.org.bjca.anysign.android.api.core.domain.BJCAAnySignAVType;
import cn.org.bjca.anysign.android.api.core.domain.BioType;
import cn.org.bjca.anysign.android.api.core.domain.CommentInputType;
import cn.org.bjca.anysign.android.api.core.domain.DataType;
import cn.org.bjca.anysign.android.api.core.domain.OriginalContentType;
import cn.org.bjca.anysign.android.api.core.domain.SignResult;
import cn.org.bjca.anysign.android.api.core.domain.SignatureType;
import cn.org.bjca.anysign.core.domain.BJCASignatureBoardType;
/**
 * Expose Java to JavaScript. Methods annotated with {@link ReactMethod} are exposed.
 */
final class XssSignModule extends ReactContextBaseJavaModule {

    private SignatureAPI api;
    XssSignModule(ReactApplicationContext reactContext) {
        super(reactContext);
    }

    /**
     * @return the name of this module. This will be the name used to {@code require()} this module
     * from JavaScript.
     */
    @Override
    public String getName() {
        return "XssSigner";
    }

    @ReactMethod
    void showSignatureDialog(String businessId, String signerName, String idCard, ReadableArray keywords,
      String channel,
      ReadableMap metric,
      Boolean isLandscape,
      final Promise promise) {
        Activity activity = getCurrentActivity();
        if (activity != null) {
         // Intent intent = new Intent(activity, SignatureViewActivity.class);
          //activity.startActivity(intent);
        String contentBusinessId = businessId;
        try {
            AnySignBuild.Default_Cert_EncAlg = "RSA"; // 设置签名算法，默认为RSA，可以设置成SM2
            AnySignBuild.privacyTold = false; //所有签名提示隐私协议

            api = new SignatureAPI(activity);

            // 所有api接口中设置成功返回 SignatureAPI.SUCCESS（0），其他错误
            int apiResult = api.setChannel(channel);
            if(apiResult == SignatureAPI.SUCCESS){
                Log.e("XSS", "apiResult -- setChannel：成功");
            }else{
                Log.e("XSS", "apiResult -- setChannel：失败");
            }
            InputStream is = activity.getResources().openRawResource(R.raw.test_pdf);
            byte[] bTemplate = new byte[is.available()];
            is.read(bTemplate);

            /**
             * 配置此次签名对应的模板数据
             * 参数1：表示模板类型，不可为空：如果为PDF和HTML格式，调用下面构造函数
             *        ContextID.FORMDATA_PDF：PDF格式，ContextID.FORMDATA_HTML：HTML格式
             * 参数2：表示模板数据byte数组类型，不可为空
             * 参数3：业务流水号/工单号，不可为空
             */
            apiResult = api.setOrigialContent(new OriginalContent(OriginalContentType.CONTENT_TYPE_PDF, bTemplate,  contentBusinessId));
            Log.e("XSS", "apiResult -- setOrigialContent：" + apiResult);
            //			 实例化签名规则
            List<SignRule> signRules = new ArrayList<>();
            for (int i = 0; i < keywords.size(); i++) {
                String kw = keywords.getString(i);
                SignRule.KWRule kwRule = new SignRule.KWRule(kw,
                  metric.getInt("xoffset")/*20*/, metric.getInt("yoffset")/*10*/,
                  0, 1);
                SignRule signRule = SignRule.getInstance(SignRuleType.TYPE_KEY_WORD);
                signRule.setKWRule(kwRule);
                signRules.add(signRule);
            }
            //XYZRule xyzRules[] = {
            //    new XYZRule(84, 523, 200, 411, 0,"dp"),
            //    new XYZRule(44, 332, 200, 223, 0,"dp"),
            //    new XYZRule(0, 110, 200, 10, 0,"dp"),
            //};
            //for (XYZRule xyzRule: xyzRules) {
            //    SignRule signRule = SignRule.getInstance(SignRuleType.TYPE_XYZ);
            //    signRule.setXYZRule(xyzRule);
            //    signRules.add(signRule);
            //}
            Signer signer = new Signer(signerName, idCard, Signer.SignerCardType.TYPE_IDENTITY_CARD);
//			实例化手写签名对象
//			参数1：手写签名对象索引值
            BatchSignatureObj obj = new BatchSignatureObj(0,signRules,signer);

            //Signer signer = new Signer("李白", "111", SignerCardType.TYPE_IDENTITY_CARD);
            ////  实例化手写签名对象 参数1：手写签名对象索引值；参数2：签名规则；参数3：签名人信息
            //SignatureObj obj = new SignatureObj(0,signRule,signer);
            obj.single_height = (float)metric.getDouble("imageHeight");//30; //  设置签名图片高度，单位dip
            obj.single_width = (float)metric.getDouble("imageWidth");//45; //   设置签名图片宽度，单位dip
            //  手写识别开关，true为开启手写识别，false为关闭手写识别
            obj.isdistinguish = false;
            //  识别错误的次数，超过识别错误个数时直接跳出识别，直接返回结果。默认为0时，一直走识别。此参数的前提是识别系统为true时
            obj.ocrErrorTime = 3;
            //  签名是否必须,设置为true时必须进行签名，默认true
            obj.nessesary = false;
            //  设置签名笔迹颜色，默认为黑色
            //obj.penColor = Color.RED;
            //  用钢笔/毛笔字模式,true为钢笔，false为毛笔
            obj.isNoBrushes = true;
            //  签名笔迹大小
            obj.penSize = 15;
            //  需要显示在签名框顶栏的标题
            obj.title = String.format("请%s签字", signerName);
            //  单字签名框中需要突出显示部分的起始位置和结束位置
            obj.titleSpanFromOffset = 1;
            //  单字签名框中需要突出显示部分的起始位置和结束位置
            obj.titleSpanToOffset = signerName.length();;
            //  识别错误提示语
            obj.distinguishErrorText = "识别错误";
            //  显示框的类型
            obj.signatureBoardType = BJCASignatureBoardType.BJCAAnySignWordNumberTransformType;
               // BJCASignatureBoardType.BJCAAnySignMultiwordType;

            ////  注册单签签名对象
            //apiResult = api.addSignatureObj(obj);
            //Log.e("XSS", "apiResult -- addSignatureObj：" + apiResult);
//			 注册单签签名对象
            apiResult = api.addBatchSignatureObj(obj);
            Log.e("XSS", "apiResult -- addSignatureObj：" + apiResult);
            apiResult = api.showSignatureDialog(0);// 弹出单签签名框签名
            Log.e("XSS", "apiResult -- showSignatureDialog：" + apiResult);
            /*
             * 注册签名结果回调函数
             */
            api.setOnSignatureResultListener(new OnSignatureResultListener() {

                @Override
                public void onSignResult(final SignResult signResult)
                {
                    //showImgPreviewDlg(signResult.signature, activity);

                    //if(signResult.eviPic != null && signResult.eviPic.length != 0){
                    //    activity.runOnUiThread(new Runnable()
                    //    {
                    //        public void run()
                    //        {
                    //            Bitmap camera_pic = BitmapFactory.decodeByteArray(signResult.eviPic, 0, signResult.eviPic.length);
                    //            showImgPreviewDlg(camera_pic, activity);

                    //        }
                    //    });
                    //}

                    Log.e("XSS", "onSignResult signIndex : " + signResult.signIndex + "  resultCode : " + signResult.resultCode+ "  signType : " + signResult.signType
                            + "  eviPic : " + signResult.eviPic);

                List<String> list = (ArrayList<String>)api.genSignRequest();
                if(list != null){
                    WritableArray signEncArray= Arguments.createArray();
                    WritableMap map = Arguments.createMap();
                    for (int i = 0; i < list.size(); i++) {
                        signEncArray.pushString(list.get(i));
                        Log.e("XSS", "onSignResult genSignRequest: " + i + list.get(i));
                    }
                    map.putArray("signEncs", signEncArray);
                    // https://stackoverflow.com/questions/9224056/android-bitmap-to-base64-string
                    //Don't forget the manifest permission to write files
                    //final FileOutputStream fos = new FileOutputStream(yourFileHere);
                    //bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
                    //
                    //fos.close();
                    //
                    //final InputStream is = new Base64InputStream( new FileInputStream(yourFileHere) );
                    //
                    // //Now that we have the InputStream, we can read it and put it into the String
                    //final StringWriter writer = new StringWriter();
                    //IOUtils.copy(is , writer, encoding);
                    //final String yourBase64String = writer.toString();
                    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                    signResult.signature.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
                    String signImg = Base64.encodeToString(outputStream.toByteArray(), Base64.NO_WRAP);
                    map.putString("signImgBase64", signImg);
                    promise.resolve(map);
                    //Toast.makeText(SignatureViewActivity.this,"打包成功",Toast.LENGTH_SHORT).show();
                }else{
                    //Toast.makeText(SignatureViewActivity.this,"打包失败",Toast.LENGTH_SHORT).show();
                    Log.e("XSS", "onSignResult genSignRequest: null");
                    promise.reject("onSignResult genSignRequest: null");
                }

                }

                @Override
                public void onCancel(int index, SignatureType signType)
                {
                    Log.e("XSS", "onCancel index : " + index + "  signType : " + signType);
                    WritableMap map = Arguments.createMap();
                    promise.resolve(map);

                }

                @Override
                public void onDismiss(int index, SignatureType signType)
                {
                    Log.e("XSS", "onDismiss index : " + index + "  signType : " + signType);
                }

            });
        } catch (Exception ex) {
            ex.printStackTrace();
        }
      }
    }
    private void showImgPreviewDlg(Bitmap img, Activity activity) {
        ImageView iv = new ImageView(activity);
        iv.setBackgroundColor(Color.WHITE);
        iv.setImageBitmap(img);
        new AlertDialog.Builder(activity).setView(iv).show();
    }
}
